/************************************************************************

								Heroes IV
					  Copyright 2001, The 3DO Company

	------------------------------------------------------------------
  						 obelisk_data.cpp

	$Header: $

	$NoKeywords: $

 ************************************************************************/


#include "precompiled.h"
#include "obelisk_data.h"

#include <limits>

#include "default_obelisk_rewards.h"
#include "obelisk_reward.h"
#include "sized_int_types.h"
#include "streambuf_operators.h"

namespace
{
	t_uint16 const k_current_version = 0;
}

// -------------------------------------------------------------------
// t_obelisk_data members
// -------------------------------------------------------------------

// -------------------------------------------------------------------
// -------------------------------------------------------------------
t_obelisk_data::t_obelisk_data()
{
	clear_needed_count();
	set_reward_list_to_defaults( k_obelisk_gold );
}

// -------------------------------------------------------------------
// Clear the needed count -- return to default of "player must touch
// all obelisks to see map"
// -------------------------------------------------------------------
void t_obelisk_data::clear_needed_count()
{
	m_needed_count = std::numeric_limits< t_uint16>::max();
}

// -------------------------------------------------------------------
// Read from save file
// -------------------------------------------------------------------
bool t_obelisk_data::read( t_obelisk_color color, std::streambuf &stream, int file_version )
{
	if ( file_version >= 10 )
	{
		t_uint16 version = get< t_uint16 >( stream );

		if ( version > k_current_version )
			return false;

		m_needed_count = get< t_uint16 >( stream );

		t_uint16 count = get< t_uint16 >( stream );

		m_rewards.clear();

		m_rewards.reserve( count );

		while ( count )
		{
			t_obelisk_reward_ptr reward = t_obelisk_reward::read( stream );

			if ( reward.get() == NULL )
				return false;

			m_rewards.push_back( reward );

			count--;
		}
	}
	else
	{
		clear_needed_count();
		set_reward_list_to_defaults( color );
	}

	return true;
}

// -------------------------------------------------------------------
// Read from map file
// -------------------------------------------------------------------
bool t_obelisk_data::read_from_map( t_obelisk_color color, std::streambuf &stream, int map_version )
{
	if ( map_version < 13 )
	{
		clear_needed_count();
		set_reward_list_to_defaults( color );
		return true;
	}

	t_uint16 version = get< t_uint16 >( stream );

	if ( version > k_current_version )
		return false;

	bool has_custom_reward_list = get< bool >( stream );

	m_needed_count = get< t_uint16 >( stream );
	
	if ( has_custom_reward_list )
	{
		t_uint16 count = get< t_uint16 >( stream );

		m_rewards.clear();

		m_rewards.reserve( count );

		while ( count )
		{
			t_obelisk_reward_ptr reward = t_obelisk_reward::read_from_map( stream );

			if ( reward.get() == NULL )
				return false;

			m_rewards.push_back( reward );

			count--;
		}
	}
	else
	{
		set_reward_list_to_defaults( color );
	}

	return true;
}

// -------------------------------------------------------------------
// Set the reward list to the defaults for the given color
// -------------------------------------------------------------------
void t_obelisk_data::set_reward_list_to_defaults( t_obelisk_color color )
{
	m_rewards.clear();

	m_rewards.push_back( new t_obelisk_reward_artifact( k_default_obelisk_artifact[ color ] ) );
}

// -------------------------------------------------------------------
// Write to save file
// -------------------------------------------------------------------
bool t_obelisk_data::write( std::streambuf &stream ) const
{
	put< t_uint16 >( stream, k_current_version );

	put< t_uint16 >( stream, m_needed_count );

	t_uint16 count = m_rewards.size();
	
	put< t_uint16 >( stream, count );

	t_obelisk_reward_list::const_iterator it;

	for ( it = m_rewards.begin(); it != m_rewards.end(); it++ )
	{
		if ( !(*it)->write( stream ) )
			return false;
	}

	return true;
}
